<?php
/**
 * @purpose
 * @Author: Madou
 * @Time  : 2022/8/2 18:10
 */

namespace App\Trip\Orders\BookOrders\TaskEdit;

use App\Models\Task\SnapTasks\SnapTask;
use App\Trip\Orders\BookOrders\Params\Param;
use App\Trip\Orders\BookOrders\Train\Order\SnapNewOrder;
use Exception;
use Illuminate\Support\Facades\Log;

class TaskEditOrder
{

    private Param        $param;
    private SnapNewOrder $order_builder;
    private array        $build_order_info;

    /**
     * 原则上只计算 乘客票价 其余均不可修改
     *
     * @throws Exception
     */
    public function __construct(Param $param)
    {
        $this->param         = $param;
        $this->order_builder = new SnapNewOrder($this->param->getEditSnapOrderParam(), $this->param);
    }

    public function getOrderBuilder(): SnapNewOrder
    {
        return $this->order_builder;
    }

    /**
     * @throws Exception
     */
    public function getEditPay(): TaskEditPayData
    {
        return new TaskEditPayData($this);
    }

    /**
     * 是否更改了编辑参数
     * @throws Exception
     */
    public function isEditNotChange(): bool
    {
        return $this->getEditTripKey() == $this->getCurrOrderTripKey();
    }

    public function getEditTripKey(): string
    {
        $params                       = $this->getParam()->getParams();
        $task_id                      = $params['task_id'];
        $user_id                      = $params["user_id"];
        $useful                       = collect($params['order'])->only([
            'to_code',
            'from_code',
            'start_at',
            'arrive_at',
            'train_code',
            'alternative_seats',
            'alternative_trains',
            'alternative_train_dates',
        ])->toArray();
        $alternative_trains           = collect($useful['alternative_trains'])
            ->map(function ($trains) {
                $res = collect($trains)->only([
                    'to_code',
                    'from_code',
                    'train_code',
                    'start_time',
                    'arrive_time',
                ])->toArray();
                ksort($res);
                return $res;
            })->toArray();
        $useful['alternative_trains'] = $alternative_trains;
        ksort($useful);
        $seed = compact('useful', 'user_id', 'task_id');
        ksort($seed);
        $key = collect($seed)->toJson(JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        Log::info("edit_order_key:".$key);
        return md5($key);
    }

    public function getParam(): Param
    {
        return $this->param;
    }

    /**
     * @throws Exception
     */
    public function getCurrOrderTripKey(): string
    {
        $order = $this->getTaskInfo()?->getTrainOrderInfo();
        if (!$order) {
            return '';
        }

        $task_id = $order->getTaskId();
        $user_id = $order->getUserId();
        $train   = $order->getTrainInfo();
        $useful  = [
            'to_code'                 => $order->getToStationCode(),
            'from_code'               => $order->getFromStationCode(),
            'start_at'                => $train->getStartAt(),
            'arrive_at'               => $train->getArriveAt(),
            'train_code'              => $order->getTrainCode(),
            'alternative_seats'       => $order->getAlternativeSeats(),
            'alternative_trains'      => collect($order->getAlternativeTrains())
                ->map(function ($trains) {
                    $res = collect($trains)->only([
                        'to_code',
                        'from_code',
                        'train_code',
                        'start_time',
                        'arrive_time',
                    ])->toArray();
                    ksort($res);
                    return $res;
                })->toArray(),
            'alternative_train_dates' => $order->getAlternativeTrainDates(),
        ];
        ksort($useful);
        $seed = compact('useful', 'user_id', 'task_id');
        ksort($seed);
        $key = collect($seed)->toJson(JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        Log::info("origin_order_key:".$key);
        return md5($key);

    }

    /**
     * @throws Exception
     */
    public function getTaskInfo(): SnapTask
    {
        return $this->param->getEditSnapOrderParam()->getSnapParam()->getTaskInfo();
    }

}